const socketio = require('socket.io');
const nickNames = {};
const nameUsed = [];
const currentRoom = {};

let io = null;
let guestNum = 1;

function assignGuestName(socket, num, nickNames, nameUsed) {
	const name = 'Guest' + num;
	nickNames[socket.id] = name;
	socket.emit('nameResult', {
		success: true,
		name: name
	});

	nameUsed.push(name);
	return num + 1;
}

function joinRoom(socket, room) {
	socket.join(room);
	currentRoom[socket.id] = room;
	socket.emit('joinResult', { room: room });
	socket.broadcast.to(room).emit('message', {
		text: nickNames[socket.id] + 'has joined' + room + '.'
	});
	const usersRoom = io.sockets.clients(room);
	if(usersName.length > 1) {
		var usersInRoomSummary = 'Users currently in ' + room + ': ';
		for(var index in usersRoom) {
			const userSocketId = usersRoom[index].id;
			if(userSocketId === socket.id) {
				continue;
			}

			if(index > 0) {
				usersInRoomSummary += ', ';
			}
			usersInRoomSummary += nickNames[userSocketId];
		}

		usersInRoomSummary += '.';
		socket.emit('message', { text: usersInRoomSummary });
	}
}

function handleNameChangeAttempts(socket, nickNames, nameUsed) {
	socket.on('nameAttempt', function (name) {
		if(name.indexOf('Guest') === 0) {
			socket.emit('nameResult', {
				success: false,
				message: '不能使用Guest开头的名字'
			});
		} else {
			if(nameUsed.indexOf(name) > -1) {
				var previousName = nickNames[socket.id];
				var previousNameIndex = nameUsed.indexOf(previousName);

				nickNames[socket.id] = name;
				delete nameUsed[previousNameIndex];
				nameUsed.push(name;)
				socket.emit('nameResult', {
					success: true,
					name: name
				});

				socket.broadcast.to(currentRoom[socket.id]).emit('message', {
					text: previousName + ' 更换为: ' + name
				});
			} else {
				socket.emit('nameResult', {
					success: false,
					message: '被占用!'
				});
			}
		}
	});
}

function handleMessageBroadcasting(socket) {
	socket.on('message', function (message) {
		socket.broadcast.to(message.room).emit('message', {
			text: nickNames[socket.id] + ': ' + message.text
		});
	});
}

function handleRoomJoining(socket) {
	socket.on('join', function (room) {
		socket.leave(currentRoom[socket.id]);
		joinRoom(socket, room.newRoom);
	});
}

function handleClientDisconnection(socket, nickNames, nameUsed) {
	socket.on('disconnect', function () {
		var nameIndex = nameUsed.indexOf(nickNames[socket.id]);

		delete nickNames[socket.id];
		delete nameUsed[nameIndex];
	});
}

exports.listen = function (server) {
	io = socketio.listen(server);
	io.set('log level', 1);
	io.sockets.on('connection', function (socket) {
		guestNum = assignGuestName(socket, guestNum, nickNames, nameUsed);
		joinRoom(socket, 'Lobby');
		handleMessageBroadcasting(socket);
		handleNameChangeAttempts(socket, nickNames, nameUsed);
		handleRoomJoining(socket);

		socket.on('rooms', function () {
			socket.emit('rooms', io.sockets.manager.rooms);
		});

		handleClientDisconnection(socket, nickNames, nameUsed);
	});
};